home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
os2
/
pvm34b3.zip
/
pvm34b3
/
pvm3
/
src
/
waitc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-22
|
8KB
|
372 lines
static char rcsid[] =
"$Id: waitc.c,v 1.6 1997/06/27 17:32:59 pvmsrc Exp $";
/*
* PVM version 3.4: Parallel Virtual Machine System
* University of Tennessee, Knoxville TN.
* Oak Ridge National Laboratory, Oak Ridge TN.
* Emory University, Atlanta GA.
* Authors: J. J. Dongarra, G. E. Fagg, M. Fischer
* G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
* P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
* (C) 1997 All Rights Reserved
*
* NOTICE
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted
* provided that the above copyright notice appear in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* Neither the Institutions (Emory University, Oak Ridge National
* Laboratory, and University of Tennessee) nor the Authors make any
* representations about the suitability of this software for any
* purpose. This software is provided ``as is'' without express or
* implied warranty.
*
* PVM version 3 was funded in part by the U.S. Department of Energy,
* the National Science Foundation and the State of Tennessee.
*/
/*
* waitc.c
*
* Wait context descriptors.
*
$Log: waitc.c,v $
* Revision 1.6 1997/06/27 17:32:59 pvmsrc
* Updated for WIN32 header files & Authors.
*
* Revision 1.5 1997/03/06 21:50:24 pvmsrc
* Yanked out #includes for <netinet/in.h> and <netinet/tcp.h>.
* - dups with lpvm.h #includes...
*
* Revision 1.4 1997/01/28 19:27:52 pvmsrc
* New Copyright Notice & Authors.
*
* Revision 1.3 1996/10/25 13:58:10 pvmsrc
* Replaced old #includes for protocol headers:
* - <pvmsdpro.h>, "ddpro.h", "tdpro.h"
* With #include of new combined header:
* - <pvmproto.h>
*
* Revision 1.2 1996/10/24 21:18:31 pvmsrc
* Moved #include "global.h" to end of #include's for typing.
* Added #include of new "lpvm.h" in place of explicitly extern-ed
* globals...
*
* Revision 1.1 1996/09/23 23:44:47 pvmsrc
* Initial revision
*
* Revision 1.6 1995/11/02 16:36:44 manchek
* added NEEDSENDIAN switch
*
* Revision 1.5 1995/07/28 16:04:07 manchek
* switch endian includes on flag, not arch name
*
* Revision 1.4 1995/07/19 21:27:33 manchek
* use new function pvmnametag instead of [dts]mname
*
* Revision 1.3 1994/07/18 19:25:18 manchek
* wait_get() checks hostpart, ignoring TIDPVMD.
* added create/free logging
*
* Revision 1.2 1994/06/03 20:38:32 manchek
* version 3.3.0
*
* Revision 1.1 1993/08/30 23:26:52 manchek
* Initial revision
*
*/
#include <stdio.h>
#ifdef NEEDMENDIAN
#include <machine/endian.h>
#endif
#ifdef NEEDENDIAN
#include <endian.h>
#endif
#ifdef NEEDSENDIAN
#include <sys/endian.h>
#endif
#ifndef WIN32
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <sys/time.h>
#include <sys/socket.h>
#else
#include "..\xdr\types.h"
#include "..\xdr\xdr.h"
#endif
#ifdef IMA_TITN
#include <bsd/sys/types.h>
#else
#include <sys/types.h>
#endif
#ifdef SYSVSTR
#include <string.h>
#else
#include <strings.h>
#endif
#include <pvm3.h>
#include <pvmproto.h>
#include "pvmalloc.h"
#include "pmsg.h"
#include "listmac.h"
#include "bfunc.h"
#include "lpvm.h"
#include "host.h"
#include "waitc.h"
#include "global.h"
/***************
** Globals **
** **
***************/
extern void pvmbailout();
char *pvmnametag();
/***************
** Private **
** **
***************/
static int widbase = 0;
static int widrange = ~0;
static char *waitnames[] = {
"addhost", "spawn", "hoststart", "task",
"delhost", "htupd", "pstat", "taskx",
"mstat", "db", "hostf", "hosta", "hostsync",
"taskstart",
"routea", "routed"
};
static char *
waitkind(kind)
int kind;
{
if (kind < 1 || kind > sizeof(waitnames)/sizeof(waitnames[0]))
return "???";
return waitnames[kind - 1];
}
/*****************
** Interface **
** **
*****************/
/* wait_init()
*
* Call this boy before any other wait stuff.
*/
void
wait_init(base, range)
int base; /* base value for wait context ids */
int range; /* mask for id generation */
{
if (!waitlist) {
widbase = base;
widrange = range;
waitlist = TALLOC(1, struct waitc, "wait");
BZERO((char*)waitlist, sizeof(struct waitc));
waitlist->wa_link = waitlist;
waitlist->wa_rlink = waitlist;
}
}
/* wait_new()
*
* Create new wait context of given kind with no peers. Add to
* active list.
*/
struct waitc *
wait_new(kind)
int kind;
{
static int lastwid = 0; /* last wid assigned */
int startwid; /* to detect when we've tried all */
int wid;
struct waitc *wp, *wp2;
/*
* find a unique wid by incrementing lastwid and stepping through
* waitlist until we find a vacant slot.
*/
if (++lastwid > widrange)
lastwid = 1;
startwid = lastwid;
wp = waitlist;
while (1) {
wid = widbase + lastwid;
while (wp->wa_wid < wid)
if ((wp = wp->wa_link) == waitlist)
break;
if (wp->wa_wid != wid)
break;
if (++lastwid > widrange) {
lastwid = 1;
wp = waitlist;
}
if (lastwid == startwid) {
pvmlogprintf("wait_new() out of wids\n");
pvmbailout(0); /* XXX this is kinda harsh */
}
}
/*
* initialze new w context and add to list
*/
if (!(wp2 = TALLOC(1, struct waitc, "wait"))) {
pvmlogprintf("wait_new() can't get memory\n");
pvmbailout(0);
}
wp2->wa_wid = wid;
wp2->wa_kind = kind;
wp2->wa_peer = wp2->wa_rpeer = wp2;
wp2->wa_on = wp2->wa_tid = wp2->wa_dep = 0;
wp2->wa_mesg = 0;
wp2->wa_count = 0;
wp2->wa_spec = 0;
LISTPUTBEFORE(wp, wp2, wa_link, wa_rlink);
if (pvmdebmask & PDMWAITC) {
pvmlogprintf("wait_new():\n");
wait_dump(wp2);
}
return wp2;
}
/* wait_find()
*
* Find a wait context in active list by id. Returns pointer
* or 0 if not found.
*/
struct waitc *
wait_find(wid)
int wid;
{
struct waitc *wp;
for (wp = waitlist->wa_link; wp != waitlist; wp = wp->wa_link)
if (wp->wa_wid == wid)
return wp;
return (struct waitc*)0;
}
/* wait_delete()
*
* Remove a wait context from the active list, disassociate from
* any peers and destroy it.
*/
void
wait_delete(wp)
struct waitc *wp;
{
if (pvmdebmask & PDMWAITC) {
pvmlogprintf("wait_delete():\n");
wait_dump(wp);
}
if (wp->wa_mesg)
pmsg_unref(wp->wa_mesg);
if (wp->wa_link) {
LISTDELETE(wp, wa_link, wa_rlink);
}
if (wp->wa_peer) {
LISTDELETE(wp, wa_peer, wa_rpeer);
}
PVM_FREE(wp);
}
/* wait_get()
*
* Find the wait context in waitlist for a given message.
* If hp != 0, check that message came from correct host.
* If kind != 0, check that message is correct kind.
*/
struct waitc *
wait_get(hp, mp, kind)
struct hostd *hp;
struct pmsg *mp;
int kind;
{
struct waitc *wp;
if (!mp->m_wid)
return 0;
if (!(wp = wait_find(mp->m_wid))) {
pvmlogprintf("waitc_get() tag %s from t%x wid %d not found\n",
pvmnametag(mp->m_tag, (int *)0), mp->m_src, mp->m_wid);
return 0;
}
if (hp && hp->hd_hostpart != (wp->wa_on & TIDHOST)) {
pvmlogprintf("waitc_get() tag %s from t%x wid %d wrong host\n",
pvmnametag(mp->m_tag, (int *)0), mp->m_src, mp->m_wid);
return 0;
}
if (kind && kind != wp->wa_kind) {
pvmlogprintf("waitc_get() tag %s from t%x wid %d wrong kind: %s\n",
pvmnametag(mp->m_tag, (int *)0), mp->m_src, mp->m_wid,
waitkind(wp->wa_kind));
return 0;
}
return wp;
}
void
wait_dump(wp)
struct waitc *wp;
{
struct waitc *wp2;
pvmlogprintf("wid %d kind %s on 0x%x tid 0x%x dep %d peer {",
wp->wa_wid,
waitkind(wp->wa_kind),
wp->wa_on,
wp->wa_tid,
wp->wa_dep);
for (wp2 = wp->wa_peer; wp2 != wp; wp2 = wp2->wa_peer)
pvmlogprintf(" %d", wp2->wa_wid);
pvmlogprintf(" } cnt %d\n", wp->wa_count);
}
void
wait_dumpall()
{
struct waitc *wp;
pvmlogprintf("wait_dumpall()\n");
for (wp = waitlist->wa_link; wp != waitlist; wp = wp->wa_link)
wait_dump(wp);
}